<!-- eslint-disable max-len -->
<template>
  <div class="panel-tab__content">
    <el-table :data="elementListenersList" size="mini" border>
      <el-table-column :label="$t('serialNo')" width="80px" type="index" />
      <el-table-column
        :label="$t('eventType')"
        min-width="100pxpx"
        show-overflow-tooltip
        :formatter="row => $t(listenerEventTypeObject[row.event])" />
      <el-table-column :label="$t('eventId')" min-width="100px" prop="id" show-overflow-tooltip />
      <el-table-column
        :label="$t('listenerType')"
        min-width="100px"
        show-overflow-tooltip
        :formatter="row => $t(listenerTypeObject[row.listenerType])" />
      <el-table-column :label="$t('operation')" width="90px">
        <template slot-scope="{ row, $index }">
          <el-button size="mini" type="text" @click="openListenerForm(row, $index)">{{ $t('edit') }}</el-button>
          <el-divider direction="vertical" />
          <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeListener(row, $index)">{{
            $t('remove')
          }}</el-button>
        </template>
      </el-table-column>
      <template slot="empty">
        <loading-state :outsidePosition="true" style="position: unset;" :echartShowStatus="3"></loading-state>
      </template>
    </el-table>
    <div class="element-drawer__button">
      <el-button size="mini" type="primary" icon="el-icon-plus" @click="openListenerForm(null)">{{
        $t('addListener')
      }}</el-button>
    </div>

    <!-- 监听器 编辑/创建 部分 -->
    <el-drawer
      class="listener-drawer-wrap"
      :visible.sync="listenerFormModelVisible"
      :title="$t('taskListener')"
      :size="`${width}px`"
      append-to-body
      destroy-on-close>
      <div class="listener-drawer-body_content">
        <el-form size="mini" :model="listenerForm" label-width="96px" ref="listenerFormRef" @submit.native.prevent>
          <el-form-item :label="$t('eventType')" prop="event" :rules="{ required: true, trigger: ['blur', 'change'] }">
            <el-select v-model="listenerForm.event">
              <el-option
                v-for="i in Object.keys(listenerEventTypeObject)"
                :key="i"
                :label="$t(listenerEventTypeObject[i])"
                :value="i" />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('listenerId')" prop="id" :rules="{ required: true, trigger: ['blur', 'change'] }">
            <el-input v-model="listenerForm.id" clearable />
          </el-form-item>
          <el-form-item
            :label="$t('listenerType')"
            prop="listenerType"
            :rules="{ required: true, trigger: ['blur', 'change'] }">
            <el-select v-model="listenerForm.listenerType">
              <el-option
                v-for="i in Object.keys(listenerTypeObject)"
                :key="i"
                :label="$t(listenerTypeObject[i])"
                :value="i" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="listenerForm.listenerType === 'classListener'"
            :label="$t('javaClass')"
            prop="class"
            key="listener-class"
            :rules="{ required: true, trigger: ['blur', 'change'] }">
            <el-input v-model="listenerForm.class" clearable />
          </el-form-item>
          <el-form-item
            v-if="listenerForm.listenerType === 'expressionListener'"
            :label="$t('expression')"
            prop="expression"
            key="listener-expression"
            :rules="{ required: true, trigger: ['blur', 'change'] }">
            <el-input v-model="listenerForm.expression" clearable />
          </el-form-item>
          <el-form-item
            v-if="listenerForm.listenerType === 'delegateExpressionListener'"
            :label="$t('registerExpression')"
            prop="delegateExpression"
            key="listener-delegate"
            :rules="{ required: true, trigger: ['blur', 'change'] }">
            <el-input v-model="listenerForm.delegateExpression" clearable />
          </el-form-item>
          <template v-if="listenerForm.listenerType === 'scriptListener'">
            <el-form-item
              :label="$t('scriptFormat')"
              prop="scriptFormat"
              key="listener-script-format"
              :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }">
              <el-input v-model="listenerForm.scriptFormat" clearable />
            </el-form-item>
            <el-form-item
              :label="$t('scriptType')"
              prop="scriptType"
              key="listener-script-type"
              :rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }">
              <el-select v-model="listenerForm.scriptType">
                <el-option :label="$t('inlineScript')" value="inlineScript" />
                <el-option :label="$t('externalScript')" value="externalScript" />
              </el-select>
            </el-form-item>
            <el-form-item
              v-if="listenerForm.scriptType === 'inlineScript'"
              :label="$t('scriptContent')"
              prop="value"
              key="listener-script"
              :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }">
              <el-input v-model="listenerForm.value" clearable />
            </el-form-item>
            <el-form-item
              v-if="listenerForm.scriptType === 'externalScript'"
              :label="$t('resourceAdress')"
              prop="resource"
              key="listener-resource"
              :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }">
              <el-input v-model="listenerForm.resource" clearable />
            </el-form-item>
          </template>

          <template v-if="listenerForm.event === 'timeout'">
            <el-form-item :error="$t('timerType')" prop="eventDefinitionType" key="eventDefinitionType">
              <el-select v-model="listenerForm.eventDefinitionType">
                <el-option :label="$t('date')" value="date" />
                <el-option :label="$t('duration')" value="duration" />
                <el-option :label="$t('loop')" value="cycle" />
                <el-option :label="$t('none')" value="null" />
              </el-select>
            </el-form-item>
            <el-form-item
              v-if="!!listenerForm.eventDefinitionType && listenerForm.eventDefinitionType !== 'null'"
              :label="$t('timer')"
              prop="eventTimeDefinitions"
              key="eventTimeDefinitions"
              :rules="{ required: true, trigger: ['blur', 'change'], message: '请填写定时器配置' }">
              <el-input v-model="listenerForm.eventTimeDefinitions" clearable />
            </el-form-item>
          </template>
        </el-form>

        <el-divider />
        <p class="listener-filed__title">
          <span><i class="el-icon-menu"></i>{{ $t('insertCharacter') }}</span>
          <el-button size="mini" type="primary" @click="openListenerFieldForm(null)">{{
            $t('addCharacter')
          }}</el-button>
        </p>
        <el-table
          :data="fieldsListOfListener"
          size="mini"
          max-height="240"
          border
          fit
          style="flex: none">
          <el-table-column :label="$t('serialNo')" width="80px" type="index" />
          <el-table-column :label="$t('characterName')" min-width="110px" prop="name" />
          <el-table-column
            :label="$t('characterType')"
            min-width="110px"
            show-overflow-tooltip
            :formatter="row => $t(fieldTypeObject[row.fieldType])" />
          <el-table-column
            :label="$t('charactOrExpre')"
            min-width="120px"
            show-overflow-tooltip
            :formatter="row => row.string || row.expression" />
          <el-table-column :label="$t('operation')" width="100px">
            <template slot-scope="{ row, $index }">
              <el-button size="mini" type="text" @click="openListenerFieldForm(row, $index)">{{
                $t('edit')
              }}</el-button>
              <el-divider direction="vertical" />
              <el-button size="mini" type="text" style="color: #ff4d4f" @click="removeListenerField(row, $index)">{{
                $t('remove')
              }}</el-button>
            </template>
          </el-table-column>
          <template slot="empty">
            <loading-state :outsidePosition="true" style="position: unset;" :echartShowStatus="3"></loading-state>
          </template>
        </el-table>

        <div class="element-drawer__button">
          <el-button size="mini" @click="listenerFormModelVisible = false">{{ $t('cancel') }}</el-button>
          <el-button size="mini" type="primary" @click="saveListenerConfig">{{ $t('save') }}</el-button>
        </div>
      </div>
    </el-drawer>

    <!-- 注入西段 编辑/创建 部分 -->
    <el-dialog
      :title="$t('charactConfig')"
      :visible.sync="listenerFieldFormModelVisible"
      width="600px"
      append-to-body
      destroy-on-close>
      <el-form
        :model="listenerFieldForm"
        size="mini"
        label-width="auto"
        ref="listenerFieldFormRef"
        style="height: 136px"
        @submit.native.prevent>
        <el-form-item :label="$t('characterName')" prop="name" :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.name" clearable />
        </el-form-item>
        <el-form-item
          :label="$t('characterType')"
          prop="fieldType"
          :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-select v-model="listenerFieldForm.fieldType">
            <el-option v-for="i in Object.keys(fieldTypeObject)" :key="i" :label="$t(fieldTypeObject[i])" :value="i" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'string'"
          :label="$t('characterValue')"
          prop="string"
          key="field-string"
          :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.string" clearable />
        </el-form-item>
        <el-form-item
          v-if="listenerFieldForm.fieldType === 'expression'"
          :label="$t('expression')"
          prop="expression"
          key="field-expression"
          :rules="{ required: true, trigger: ['blur', 'change'] }">
          <el-input v-model="listenerFieldForm.expression" clearable />
        </el-form-item>
      </el-form>
      <template slot="footer">
        <el-button size="mini" @click="listenerFieldFormModelVisible = false">{{ $t('cancel') }}</el-button>
        <el-button size="mini" type="primary" @click="saveListenerFiled">{{ $t('sure') }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { createListenerObject, updateElementExtensions } from '../../utils'
import { initListenerForm, initListenerType, eventType, listenerType, fieldType } from './utilSelf'

export default {
  name: 'UserTaskListeners',
  props: {
    // eslint-disable-next-line vue/require-default-prop
    id: String,
    // eslint-disable-next-line vue/require-default-prop
    type: String
  },
  inject: {
    prefix: 'prefix',
    width: 'width'
  },
  data () {
    return {
      elementListenersList: [],
      listenerEventTypeObject: eventType,
      listenerTypeObject: listenerType,
      listenerFormModelVisible: false,
      listenerForm: {},
      fieldTypeObject: fieldType,
      fieldsListOfListener: [],
      listenerFieldFormModelVisible: false, // 监听器 注入字段表单弹窗 显示状态
      editingListenerIndex: -1, // 监听器所在下标，-1 为新增
      editingListenerFieldIndex: -1, // 字段所在下标，-1 为新增
      listenerFieldForm: {}, // 监听器 注入字段 详情表单,
      otherExtensionList: []
    }
  },
  watch: {
    id: {
      immediate: true,
      handler (val) {
        val && val.length && this.$nextTick(() => this.resetListenersList())
      }
    }
  },
  methods: {
    resetListenersList () {
      this.bpmnElement = window.bpmnInstances.bpmnElement
      this.bpmnElementListeners = []
      if (this.bpmnElement.businessObject && this.bpmnElement.businessObject.extensionElements) {
        if (this.bpmnElement.businessObject.extensionElements.values) {
          // eslint-disable-next-line max-len
          this.bpmnElementListeners = this.bpmnElement.businessObject.extensionElements.values.filter(ex => ex.$type === `${this.prefix}:TaskListener`)
        }
      }
      this.elementListenersList = this.bpmnElementListeners.map(listener => initListenerType(listener))
      console.log(this.elementListenersList, this.bpmnElementListeners, 'this.elementListenersList')
    },
    openListenerForm (listener, index) {
      if (listener) {
        this.listenerForm = initListenerForm(listener)
        this.editingListenerIndex = index
      } else {
        this.listenerForm = {}
        this.editingListenerIndex = -1 // 标记为新增
      }
      if (listener && listener.fields) {
        // eslint-disable-next-line max-len
        this.fieldsListOfListener = listener.fields.map(field => ({ ...field, fieldType: field.string ? 'string' : 'expression' }))
      } else {
        this.fieldsListOfListener = []
        this.$set(this.listenerForm, 'fields', [])
      }
      // 打开侧边栏并清楚验证状态
      this.listenerFormModelVisible = true
      this.$nextTick(() => {
        if (this.$refs['listenerFormRef']) this.$refs['listenerFormRef'].clearValidate()
      })
    },
    // 移除监听器
    removeListener (listener, index) {
      this.$elConfirm(this.$t('comfirmRemove3'), this.$t('tip'), {
        confirmButtonText: this.$t('sure'),
        cancelButtonText: this.$t('cancel')
      })
        .then(() => {
          this.bpmnElementListeners.splice(index, 1)
          this.elementListenersList.splice(index, 1)
          // 保存其他配置
          this.otherExtensionList = []
          if (this.bpmnElement.businessObject && this.bpmnElement.businessObject.extensionElements) {
            if (this.bpmnElement.businessObject.extensionElements.values) {
              // eslint-disable-next-line max-len
              this.otherExtensionList = this.bpmnElement.businessObject.extensionElements.values.filter(ex => ex.$type !== `${this.prefix}:TaskListener`)
            }
          }
          updateElementExtensions(this.bpmnElement, this.otherExtensionList.concat(this.bpmnElementListeners))
        })
        .catch(() => console.info('操作取消'))
    },
    // 保存监听器
    async saveListenerConfig () {
      const validateStatus = await this.$refs['listenerFormRef'].validate()
      if (!validateStatus) return // 验证不通过直接返回
      const listenerObject = createListenerObject(this.listenerForm, true, this.prefix)
      if (this.editingListenerIndex === -1) {
        this.bpmnElementListeners.push(listenerObject)
        this.elementListenersList.push(this.listenerForm)
      } else {
        this.bpmnElementListeners.splice(this.editingListenerIndex, 1, listenerObject)
        this.elementListenersList.splice(this.editingListenerIndex, 1, this.listenerForm)
      }
      // 保存其他配置
      this.otherExtensionList = []
      if (this.bpmnElement.businessObject && this.bpmnElement.businessObject.extensionElements) {
        if (this.bpmnElement.businessObject.extensionElements.values) {
          // eslint-disable-next-line max-len
          this.otherExtensionList = this.bpmnElement.businessObject.extensionElements.values.filter(ex => ex.$type !== `${this.prefix}:TaskListener`)
        }
      }
      updateElementExtensions(this.bpmnElement, this.otherExtensionList.concat(this.bpmnElementListeners))
      // 4. 隐藏侧边栏
      this.listenerFormModelVisible = false
      this.listenerForm = {}
    },
    // 打开监听器字段编辑弹窗
    openListenerFieldForm (field, index) {
      this.listenerFieldForm = field ? JSON.parse(JSON.stringify(field)) : {}
      this.editingListenerFieldIndex = field ? index : -1
      this.listenerFieldFormModelVisible = true
      this.$nextTick(() => {
        if (this.$refs['listenerFieldFormRef']) this.$refs['listenerFieldFormRef'].clearValidate()
      })
    },
    // 保存监听器注入字段
    async saveListenerFiled () {
      const validateStatus = await this.$refs['listenerFieldFormRef'].validate()
      if (!validateStatus) return // 验证不通过直接返回
      if (this.editingListenerFieldIndex === -1) {
        this.fieldsListOfListener.push(this.listenerFieldForm)
        this.listenerForm.fields.push(this.listenerFieldForm)
      } else {
        this.fieldsListOfListener.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm)
        this.listenerForm.fields.splice(this.editingListenerFieldIndex, 1, this.listenerFieldForm)
      }
      this.listenerFieldFormModelVisible = false
      this.$nextTick(() => (this.listenerFieldForm = {}))
    },
    // 移除监听器字段
    removeListenerField (field, index) {
      this.$elConfirm(this.$t('comfirmRemove2'), this.$t('tip'), {
        confirmButtonText: this.$t('sure'),
        cancelButtonText: this.$t('cancel')
      })
        .then(() => {
          this.fieldsListOfListener.splice(index, 1)
          this.listenerForm.fields.splice(index, 1)
        })
        .catch(() => console.info('操作取消'))
    }
  }
}
</script>
